package com.sec.android.app.myfiles.launch;

import android.app.Activity;
import android.app.DownloadManager;
import android.content.Intent;
import android.net.Uri;

import com.sec.android.app.myfiles.MyFilesTestRunner;
import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.TestInput;
import com.sec.android.app.myfiles.facade.MyFilesFacade;
import com.sec.android.app.myfiles.info.AppConstants;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.CategoryType;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.StorageType;
import com.sec.android.app.myfiles.module.local.category.CategoryFileRecord;
import com.sec.android.app.myfiles.module.local.file.LocalFileRecord;
import com.sec.android.app.myfiles.navigation.NavigationInfo;
import com.sec.android.app.myfiles.navigation.NavigationManager;
import com.sec.android.app.myfiles.shadow.android.ShadowToast;
import com.sec.android.app.myfiles.shadow.custom.ShadowAppFeatures;
import com.sec.android.app.myfiles.shadow.custom.ShadowMyFilesLog;
import com.sec.android.app.myfiles.shadow.custom.ShadowSamsungAnalyticsLog;
import com.sec.android.app.myfiles.testFeature;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.robolectric.Robolectric;

import static com.sec.android.app.myfiles.navigation.NavigationInfo.NavigationMode;
import static org.powermock.api.mockito.PowerMockito.when;

/**
 * Created by jaebae on 2016-07-28.
 */
@RunWith(MyFilesTestRunner.class)
public class testLaunchMgr {
    private LaunchMgr mLaunchMgr;
    Activity mActivity;

    @Before
    public void setUp() throws Exception {
        NavigationManager.getInstance(testFeature.PROCESS_ID).clear();

        MyFilesFacade.create(testFeature.PROCESS_ID);
        mActivity = Robolectric.buildActivity(Activity.class).create().get();
        mLaunchMgr = LaunchMgr.getInstance(testFeature.PROCESS_ID);
        ShadowMyFilesLog.setEnableVerifyLog(true);
        ShadowToast.setEnableVerifyMsg(true);
        ShadowSamsungAnalyticsLog.setEnableVerifyLog(true);
    }

    @After
    public void tearDown() throws Exception {
        ShadowMyFilesLog.setEnableVerifyLog(false);
        ShadowToast.setEnableVerifyMsg(false);
        ShadowSamsungAnalyticsLog.setEnableVerifyLog(false);
        ShadowAppFeatures.mIsTablet = false;
    }

    @Test
    public void testGetInstance() {
        LaunchMgr launchMgr = LaunchMgr.getInstance(testFeature.PROCESS_ID + 1);
        Assert.assertNotSame(mLaunchMgr, launchMgr);
    }

    @Test
    public void testHandleCompressFileImp() {
        TestInput[] testList = TestInput.createTestData(
                new TestInput(null, "file://" + AppConstants.StoragePath.INTERNAL_ROOT + "/dir/test_file.zip", "_handleStart ret true", ""),
                new TestInput(null, "file:///dir/test_file.zip", "_handleStart ret false", mActivity.getString(R.string.unable_to_open_file))
        );


//        for (TestInput testValue : testList) {
//            Intent intent = createHandleCompressFileIntent((String) testValue.get(0));
//            mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

//            NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
//            Assert.assertNotNull(info);
//            Assert.assertEquals(NavigationMode.Preview_compress_item, info.getNavigationMode());

//            int depth = NavigationManager.getInstance(testFeature.PROCESS_ID).getDepth();
//            Assert.assertTrue(depth != 0);

//            ShadowMyFilesLog.verifyLog((String) testValue.get(1));
//            ShadowToast.verifyMsg((String) testValue.get(2));
//        }
    }

    private Intent createHandleCompressFileIntent(String fileUri) {
        Intent intent = PowerMockito.mock(Intent.class);
        when(intent.getAction()).thenReturn(Intent.ACTION_VIEW);
        when(intent.getType()).thenReturn("application/zip");
        when(intent.getStringExtra("AbsolutePath")).thenReturn(fileUri);
        when(intent.getData()).thenReturn(Uri.parse(fileUri));

        return intent;
    }

    @Test
    public void testHandleCreateDocumentImp() {
        Intent intent = PowerMockito.mock(Intent.class);
        when(intent.getAction()).thenReturn(AppConstants.Action.ACTION_CREATE_DOCUMENT);
        when(intent.getType()).thenReturn("audio/mp4");
        when(intent.getStringExtra(Intent.EXTRA_TITLE)).thenReturn("testTile");

        mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

        NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
        Assert.assertNotNull(info);
        Assert.assertEquals(NavigationMode.Select_create_doc_destination, info.getNavigationMode());

        int depth = NavigationManager.getInstance(testFeature.PROCESS_ID).getDepth();
        Assert.assertEquals(1, depth);
    }

    @Test
    public void testHandleDownloadHistoryImp() {
        Intent intent = PowerMockito.mock(Intent.class);
        when(intent.getAction()).thenReturn(DownloadManager.ACTION_VIEW_DOWNLOADS);

//        mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

//        NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
//        Assert.assertNotNull(info);
//        Assert.assertEquals(NavigationMode.Normal, info.getNavigationMode());

//        int depth = NavigationManager.getInstance(testFeature.PROCESS_ID).getDepth();
//        Assert.assertEquals(1, depth);
//        Assert.assertEquals(StorageType.Downloads, info.getCurRecord().getStorageType());
    }

    @Test
    public void testHandleExecutableRecentImp() {
        Intent intent = PowerMockito.mock(Intent.class);
        when(intent.getAction()).thenReturn(AppConstants.Action.ACTION_EXECUTABLE_RECENT);

        mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

        NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
        if (info != null) {
            Assert.assertNotNull(info);
            Assert.assertEquals(NavigationMode.Normal, info.getNavigationMode());

            int depth = NavigationManager.getInstance(testFeature.PROCESS_ID).getDepth();
      //      Assert.assertEquals(2, depth);
            Assert.assertEquals(StorageType.Recent, info.getCurRecord().getStorageType());
            NavigationManager.getInstance(testFeature.PROCESS_ID).leave();
        }
        info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
        if (info != null) {
            Assert.assertEquals(StorageType.Home, info.getCurRecord().getStorageType());
        }
    }

    @Test
    public void testHandlePathPickerImp() {
        String testPath = AppConstants.StoragePath.INTERNAL_ROOT + "/testDir";
        TestInput<StorageType>[] testList = TestInput.createTestData(
                new TestInput<>(StorageType.Local, AppConstants.Action.ACTION_PICK_SELECT_PATH, testPath, false),
                new TestInput<>(StorageType.Home, AppConstants.Action.ACTION_PICK_SELECT_PATH, null, false),
                new TestInput<>(StorageType.Home, AppConstants.Action.PICK_DOWNLOADS, null, false),
                new TestInput<>(StorageType.Local, AppConstants.Action.PICK_DOWNLOADS, testPath, false),

                new TestInput<>(StorageType.Local, AppConstants.Action.ACTION_PICK_SELECT_PATH, testPath, true),
                new TestInput<>(StorageType.Local, AppConstants.Action.ACTION_PICK_SELECT_PATH, null, true),
                new TestInput<>(StorageType.Local, AppConstants.Action.PICK_DOWNLOADS, null, true),
                new TestInput<>(StorageType.Local, AppConstants.Action.PICK_DOWNLOADS, testPath, true)
        );

        for (TestInput testValue : testList) {
            Intent intent = createPathPickerIntent((String) testValue.get(0), (String) testValue.get(1));

            ShadowAppFeatures.mIsTablet = (Boolean) testValue.get(2);
            // mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

            NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
            if (info != null) {
                FileRecord record = info.getCurRecord();

                Assert.assertNotNull(info);
                Assert.assertNotNull(record);


                Assert.assertEquals(NavigationMode.Select_destination_path, info.getNavigationMode());
                Assert.assertEquals(testValue.expected(), record.getStorageType());

                if (testValue.expected() == StorageType.Local) {
                    String expectedPath = (String) testValue.get(1);
                    if (expectedPath == null) {
                        expectedPath = AppConstants.StoragePath.INTERNAL_ROOT;
                    }
                    Assert.assertEquals(expectedPath, record.getFullPath());
                }

                Assert.assertNull(info.getCategoryFilter());
                Assert.assertNull(info.getMimeTypeFilter());
                Assert.assertNull(info.getExtensionFilter());
                Assert.assertNull(info.getPathFilter());
                Assert.assertNull(info.getPrefixFilter());
                Assert.assertEquals(1, info.getMaxSelectCnt());
            }
        }
    }

    private Intent createPathPickerIntent(String action, String path) {
        Intent intent = PowerMockito.mock(Intent.class);
        when(intent.getAction()).thenReturn(action);
        when(intent.getStringExtra(AppConstants.MyFilesExtras.URI)).thenReturn(path);

        return intent;
    }

    @Test
    public void testHandleSFinderImp() {
        TestInput[] testList = TestInput.createTestData(
                new TestInput(null, AppConstants.StoragePath.INTERNAL_ROOT + "/dir_test", AppConstants.StoragePath.INTERNAL_ROOT + "/dir_test", null),
                new TestInput(null, AppConstants.StoragePath.INTERNAL_ROOT + "/test", AppConstants.StoragePath.INTERNAL_ROOT, new LocalFileRecord(AppConstants.StoragePath.INTERNAL_ROOT + "/test"))
        );

        for (TestInput testValue : testList) {
            Intent intent = PowerMockito.mock(Intent.class);

            when(intent.getDataString()).thenReturn((String) testValue.get(0));

            mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

            NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
            Assert.assertNotNull(info);
            Assert.assertEquals(NavigationMode.Normal, info.getNavigationMode());
            Assert.assertEquals((String) testValue.get(1), info.getCurRecord().getFullPath());
            Assert.assertEquals((FileRecord) testValue.get(2), info.getFocusRecord());
        }

    }

    @Test
    public void testHandleStartFolderImp() {
        TestInput<String>[] testList = TestInput.createTestData(
                new TestInput<>("", Intent.ACTION_MAIN, AppConstants.StoragePath.INTERNAL_ROOT + "/dir_test1", false),
                new TestInput<>("", AppConstants.Action.ACTION_LAUNCH_MY_FILES, AppConstants.StoragePath.INTERNAL_ROOT + "/dir_test2", false),

                new TestInput<>("My Files opened from notification",
                        Intent.ACTION_MAIN, AppConstants.StoragePath.INTERNAL_ROOT + "/dir_test3", true),
                new TestInput<>("My Files opened from notification",
                        AppConstants.Action.ACTION_LAUNCH_MY_FILES, AppConstants.StoragePath.INTERNAL_ROOT + "/dir_test4", true)
        );


/*        for (TestInput<String> testValue : testList) {
            Intent intent = PowerMockito.mock(Intent.class);
            when(intent.getAction()).thenReturn((String) testValue.get(0));
            when(intent.getStringExtra(AppConstants.MyFilesExtras.EXTRA_START_PATH)).thenReturn((String) testValue.get(1));
            when(intent.getBooleanExtra(AppConstants.MyFilesExtras.START_FROM_NOTIFICATION, false)).thenReturn((Boolean) testValue.get(2));

            mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

            NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
            Assert.assertNotNull(info);
            Assert.assertEquals(1, NavigationManager.getInstance(testFeature.PROCESS_ID).getDepth());
            Assert.assertEquals(NavigationMode.Normal, info.getNavigationMode());
            Assert.assertEquals((String) testValue.get(1), info.getCurRecord().getFullPath());
            ShadowMyFilesLog.verifyLog(testValue.expected());
        }*/
    }


    @Test
    public void testHandleViewCategoryImp() {
        TestInput<CategoryType>[] testList = TestInput.createTestData(
                new TestInput<>(CategoryType.Image, AbsHandleLaunchImp.IMAGES),
                new TestInput<>(CategoryType.Video, AbsHandleLaunchImp.VIDEOS),
                new TestInput<>(CategoryType.Audio, AbsHandleLaunchImp.MUSIC),
                new TestInput<>(CategoryType.Document, AbsHandleLaunchImp.DOCUMENTS),
                new TestInput<>(CategoryType.Apk, AbsHandleLaunchImp.APKS));

        for (TestInput<CategoryType> testValue : testList) {
            Intent intent = PowerMockito.mock(Intent.class);
            when(intent.getAction()).thenReturn(AppConstants.Action.VIEW_CATEGORY);
            when(intent.getIntExtra(AppConstants.MyFilesExtras.EXTRA_CATEGORY_TYPE, 0)).thenReturn((Integer) testValue.get(0));

            mLaunchMgr.handleStart(testFeature.PROCESS_ID, mActivity, intent);

            NavigationInfo info = NavigationManager.getInstance(testFeature.PROCESS_ID).getCurInfo();
            Assert.assertNotNull(info);
            Assert.assertEquals(NavigationMode.Normal, info.getNavigationMode());
            Assert.assertEquals(StorageType.Category, info.getCurRecord().getStorageType());
            Assert.assertEquals(testValue.expected(), ((CategoryFileRecord) info.getCurRecord()).getCategoryType());
        }
    }

}